'''
* This is the projet for Brtc LlmOps Platform
* @Author Leon-liao <liaosiliang@alltman.com>
* @Description //TODO 
* @File: api_tool_schema.py
* @Time: 2025/9/23
* @All Rights Reserve By Brtc
'''
from flask_wtf import FlaskForm
from marshmallow import Schema, fields, pre_dump
from wtforms import StringField
from wtforms.validators import DataRequired, Length, URL, Optional

from pkg.paginator.paginator import PaginatorReq
from .schema import ListField
from internal.exception.exception import ValidateErrorException
from internal.model import ApiToolProvider, ApiTool

class UpdateApiToolProviderReq(FlaskForm):
    """更新API工具提供者请求校验"""
    name = StringField("name", validators=[
                                    DataRequired(message="工具名字不能为空"),
                                    Length(min=1, max=128, message="工具提供商名字长度应该在1-128个字之间")
                        ])
    icon = StringField("icon",validators=[
                                    DataRequired(message="工具的icon不能为空"),
                                    URL(message="工具的图片必须为URL链接")
                        ])
    openapi_schema = StringField("openapi_schema", validators=[
                                    DataRequired(message="openapi_schema字符串不能为空")
                        ])

    headers = ListField("headers", default=[])

    @classmethod
    def validate_header(cls, form, field):
        """校验headers 请求的数据是否正确， 涵盖列表校验， 列表元素校验"""
        for header in field.data:
            if not isinstance(header, dict):
                raise ValidateErrorException("headers里面的每一个元素都必须是字典")
            if set(header.keys()) != {"key", "value"}:
                raise ValidateErrorException("headers里面的每一个元素都必须包含key/value两个属性！！")


class GetApiToolProvidersWithPageReq(PaginatorReq):
    """获取API工具提供者分页请求数据"""
    search_word = StringField("search_word", validators=[Optional()])


class CreateApiToolReq(FlaskForm):
    """创建自定义api 工具请求"""
    name = StringField("name", validators=[DataRequired(message="工具名字不能为空"), Length(min=1, max=128, message="工具提供商名字长度应该在1-128个字之间")])
    icon = StringField("icon", validators=[DataRequired(message="工具的icon不能为空"), URL(message="工具的图片必须为URL链接")])
    openapi_schema=StringField("openapi_schema", validators=[DataRequired(message="openapi_schema字符串不能为空")])
    headers = ListField("headers", default=[])
    @classmethod
    def validate_header(cls, form, field):
        """校验headers 请求的数据是否正确， 涵盖列表校验， 列表元素校验"""
        for header in field.data:
            if not isinstance(header, dict):
                raise ValidateErrorException("headers里面的每一个元素都必须是字典")
            if set(header.keys()) != {"key", "value"}:
                raise ValidateErrorException("headers里面的每一个元素都必须包含key/value两个属性！！")

class GetApiToolProvidersWithPageResp(Schema):
    """获取API工具提供者分页列表数据响应"""
    id = fields.UUID()
    name = fields.String()
    icon = fields.String()
    description = fields.String()
    headers = fields.List(fields.Dict, default=[])
    tools = fields.List(fields.Dict, default=[])
    created_at = fields.Integer(dump_default=0)

    @pre_dump
    def process_data(self, data:ApiToolProvider, **kwargs):
        tools = data.tools
        return{
            "id":data.id,
            "name":data.name,
            "icon":data.icon,
            "description":data.description,
            "headers":data.headers,
            "tools":[{
                "id":tool.id,
                "description":tool.description,
                "name":tool.name,
                "inputs":[{k:v for k, v in parameter.items() if k!="in"} for parameter in tool.parameters]
            }for tool in tools],
            "created_at":int(data.created_at.timestamp())
        }


class GetApiToolResp(Schema):
    """获取工具参数返回详情"""
    id = fields.UUID()
    name = fields.String()
    description = fields.String()
    inputs = fields.List(fields.Dict, default=[])
    provider =fields.Dict()
    @pre_dump
    def process_data(self, data:ApiTool, **kwargs):
        provider = data.provider
        return {
            "id":data.id,
            "name":data.name,
            "description":data.description,
            "inputs":[{k:v for k, v in parameter.items() if k!="in" } for parameter in data.parameters],
            "provider":{
                "id":provider.id,
                "name":provider.name,
                "icon":provider.icon,
                "description":provider.description,
                "headers":provider.headers,
            }
        }


class GetApiProviderResp(Schema):
    """获取API工具提供者信息响应"""
    id = fields.UUID()
    name = fields.String()
    icon = fields.String()
    openapi_schema = fields.String()
    headers = fields.List(fields.Dict, dump_default=[])
    created_at = fields.Integer(dump_default=0)

    @pre_dump
    def process_data(self, data:ApiToolProvider, **kwargs):
       return {
            "id":data.id,
            "name":data.name,
            "icon":data.icon,
            "openapi_schema":data.openapi_schema,
            "headers":data.headers,
            "created_at":int(data.created_at.timestamp()),
        }




class ValidateOpenAPISchema(FlaskForm):
    """校验OpenAPI字符串规范请求"""
    openapi_schema = StringField("openapi_schema", validators=[
        DataRequired(message="openapi_schema字段是必须要填的不能为空")
    ])